/*
 * FSWUniCEUB - 2008
 * 
 * Este arquivo é de propriedade da Fábrica de Software do UniCEUB
 * 
 * Para mais informações entre em contato com a coordenação do
 * curso de Ciência da Computação da instituição.
 */

package br.uniceub.fsw.seguranca.facade;

import br.uniceub.fsw.arquitetura.persistencia.transacao.Transacao;
import br.uniceub.fsw.seguranca.dao.UsuarioDAO;
import br.uniceub.fsw.seguranca.vo.UsuarioVO;
import br.uniceub.fsw.util.TabelaHtml;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Facade da entidade Usuário.
 * 
 * @author Bruno Schifer Bernardi
 */
public class UsuarioFacade {
    /**
     * Mensagem de retorno do sistema.
     */
    private String message;

    /**
     * Value object do usuário.
     */
    private UsuarioVO usuario;
    
    /**
     * Objeto de acesso aos dados de usuário.
     */
    private UsuarioDAO usuarioDao;
    
    /**
     * Construtor da classe.
     */
    public UsuarioFacade() {
        this.usuarioDao = new UsuarioDAO();
    }
    
    /**
     * Getter da mensagem de retorno.
     * 
     * @return Mensagem de retorno.
     */
    public String getMessage() {
        String retorno = null;
        if(this.message == null || this.message.equals("")) {
            retorno = "&nbsp";
        } else {
            retorno = this.message;
        }
        return retorno;
    }

    /**
     * Setter da mensagem de retorno.
     * 
     * @param message Mensagem de retorno.
     */
    public void setMessage(String message) {
        this.message = message;
    }
    
    /**
     * Responsável por executar a operação selecionada pelo usuário.
     * 
     * @param req Requisição web do tipo HTTP.
     * @param resp Resposta da requisição HTTP.
     */
    public void operacao(HttpServletRequest req, HttpServletResponse resp) {
        String oper = req.getParameter("operacao");

        if(oper != null)
        {
            if (oper.equals("consultar")) {
                this.consultar(req, resp);
            }
            if (oper.equals("incluir")) {
                this.incluir(req, resp);
            }
            if (oper.equals("alterar")) {
                this.alterar(req, resp);
            }
            if (oper.equals("excluir")) {
                this.excluir(req, resp);
            }
            if (oper.equals("confirmar")) {
                this.confirmar(req, resp);
            }
        }
    }

    /**
     * Criptografa a senha do usuário utlizando o algoritmo hash MD5.
     * 
     * @param senha Senha de acesso.
     * @return Senha criptografada.
     */
    public String criptografar(String senha) {
        String senhaCriptografada = null;
        
        try  {   
            MessageDigest md = MessageDigest.getInstance("MD5");

            md.update(senha.getBytes());
            BigInteger hash = new BigInteger(1, md.digest());

            senhaCriptografada = hash.toString(16);
        } catch(NoSuchAlgorithmException ns) {
            ns.printStackTrace();
            
            System.out.println("UsuarioFacade.criptografar() - Ex: " + ns.getMessage());
            
            return null;
        }
      
        return senhaCriptografada;
    }
    
    /**
     * Retorna o usuario.
     * 
     * @return Objeto usuário.
     */
    public UsuarioVO getUsuario() {
        return this.usuario;
    }
    
    /**
     * Seta o usuário.
     * 
     * @param usuario Objeto usuário.
     */
    public void setUsuario(UsuarioVO usuario) {
        this.usuario = usuario;
    }
    
    /**
     * Consultar um usuário.
     * 
     * @param req Requisição web do tipo HTTP.
     * @param resp Resposta da requisição HTTP.
     */
    public void consultar(HttpServletRequest req, HttpServletResponse resp) {
        String idUsuarioTmp = req.getParameter("idUsuario");
        
        Integer idUsuario = null;
        
        if(idUsuarioTmp == null || idUsuarioTmp.equals("")) {
            return;
        } else {
            idUsuario = Integer.parseInt(idUsuarioTmp);
        }
        
        this.usuario = usuarioDao.consultarPorId(idUsuario);
    }

    /**
     * Incluir um usuário.
     * 
     * @param req Requisição web do tipo HTTP.
     * @param resp Resposta da requisição HTTP.
     */
    public void incluir(HttpServletRequest req, HttpServletResponse resp) {
        String noUsuario = req.getParameter("noUsuario");
        String dsSenha1 = req.getParameter("dsSenha1");
        String dsSenha2 = req.getParameter("dsSenha2");

        usuario = new UsuarioVO();
        usuario.setNoUsuario(noUsuario);
        usuario.setDsSenha(this.criptografar(dsSenha2));
        
        String mensagem = null;
        
        if(noUsuario == null || noUsuario.equals("")) {
            mensagem = "Nome do usuário obrigatório.";
        }
        else if(dsSenha1 == null || dsSenha1.equals("")) {
            mensagem = "Senha do usuário obrigatória.";
        }
        else if(dsSenha2 == null || dsSenha2.equals("")) {
            mensagem = "Confirmação de senha do usuário obrigatória.";
        }
        else if(!dsSenha1.equals(dsSenha2)) {
            mensagem = "Senhas digitadas não conferem.";
        }
        else {
            UsuarioVO usuarioCadastrado = usuarioDao.consultarUmPorLogin(noUsuario);

            if(usuarioCadastrado != null) {
                mensagem = "Usuário já cadastrado.";
            }
        }
        
        if(mensagem == null || mensagem.equals("")) {
            try {
                Transacao.iniciar();

                usuarioDao.inserir(usuario);

                Transacao.efetivar();

                mensagem = "Usuário incluído com sucesso.";
            } catch (Exception ex) {
                Transacao.desfazer();

                mensagem = "Problema na inclusão do usuário: " + ex.getMessage();
            }
        } else {
            usuario = null;
        }

        this.message = mensagem;
    }

    /**
     * Alterar um usuário.
     * 
     * @param req Requisição web do tipo HTTP.
     * @param resp Resposta da requisição HTTP.
     */
    public void alterar(HttpServletRequest req, HttpServletResponse resp) {
        String idUsuario = req.getParameter("idUsuario");
        String noUsuario = req.getParameter("noUsuario");
        String dsSenha1 = req.getParameter("dsSenha1");
        String dsSenha2 = req.getParameter("dsSenha2");

        usuario = new UsuarioVO();
        usuario.setIdUsuario(Integer.parseInt(idUsuario));
        usuario.setNoUsuario(noUsuario);
        usuario.setDsSenha(this.criptografar(dsSenha2));
        
        String mensagem = null;
        
        if(noUsuario == null || noUsuario.equals("")) {
            mensagem = "Nome do usuário obrigatório.";
        }
        else if(dsSenha1 == null || dsSenha1.equals("")) {
            mensagem = "Senha do usuário obrigatória.";
        }
        else if(dsSenha2 == null || dsSenha2.equals("")) {
            mensagem = "Confirmação de senha do usuário obrigatória.";
        }
        else if(!dsSenha1.equals(dsSenha2)) {
            mensagem = "Senhas digitadas não conferem.";
        }
        else {
            UsuarioVO usuarioCadastrado = usuarioDao.consultarUmPorIdDiferentePorLogin(Integer.parseInt(idUsuario), noUsuario);

            if(usuarioCadastrado != null) {
                mensagem = "Login já está sendo utilizado.";
            }
        }
        
        if(mensagem == null || mensagem.equals("")) {
            try {
                Transacao.iniciar();

                usuarioDao.alterar(usuario);

                Transacao.efetivar();

                mensagem = "Usuário alterado com sucesso.";
            } catch (Exception ex) {
                mensagem = "Problema na alteração do usuário: " + ex.getMessage();
            }
        } else {
            usuario = null;
        }
        
        this.message = mensagem;
    }

    /**
     * Excluir um usuário.
     * 
     * @param req Requisição web do tipo HTTP.
     * @param resp Resposta da requisição HTTP.
     */
    public void excluir(HttpServletRequest req, HttpServletResponse resp) {
        String idUsuario = req.getParameter("idUsuario");

        usuario = new UsuarioVO();
        usuario.setIdUsuario(Integer.parseInt(idUsuario));
        
        String mensagem = null;
        
        try {
            Transacao.iniciar();
            
            usuarioDao.excluir(usuario);
            
            Transacao.efetivar();
            
            mensagem = "Usuário excluído com sucesso.";
        } catch (Exception ex) {
            mensagem = "Problema na exclusão do usuário: " + ex.getMessage();
        }
        
        this.usuario = null;
        
        this.message = mensagem;
    }
    
    /**
     * Confirmar a exclusão de usuário.
     * 
     * @param req Requisição web do tipo HTTP.
     * @param resp Resposta da requisição HTTP.
     */
    public void confirmar(HttpServletRequest req, HttpServletResponse resp) {
        String idUsuario = req.getParameter("idUsuario");
        String noUsuario = req.getParameter("noUsuario");
        String dsSenha2 = req.getParameter("dsSenha2");

        usuario = new UsuarioVO();
        usuario.setIdUsuario(Integer.parseInt(idUsuario));
        usuario.setNoUsuario(noUsuario);
        usuario.setDsSenha(this.criptografar(dsSenha2));
    }

    /**
     * Retorna uma lista de usuários a partir de parâmetros da tela
     * 
     * @param req Requisição web do tipo HTTP.
     * @param resp Resposta da requisição HTTP.
     * @return objeto tabela com as informações necessárias
     */
    public TabelaHtml consultarUsuarios(HttpServletRequest req, HttpServletResponse resp) {
        String nome = req.getParameter("dsLogin");
        
        if(nome != null && !nome.equals("")) {
            TabelaHtml tabela = new TabelaHtml();
            
            tabela.setCampoRetorno("idUsuario");
            
            tabela.adicionarTitulo("Id");
            tabela.adicionarTamanho(0);
            tabela.adicionarTipo("Integer");
            tabela.adicionarStatus(false);

            tabela.adicionarTitulo("Nome");
            tabela.adicionarTamanho(80);
            tabela.adicionarTipo("String");
            tabela.adicionarStatus(true);
            
            tabela.gravarCampos();
            
            // Lista de usuários
            UsuarioVO exemplo = new UsuarioVO();
            exemplo.setNoUsuario(nome);
            List<UsuarioVO> usuarios = usuarioDao.consultarPorExemplo(exemplo);
            
            // Adiciona os valores de cada usuário nas listas de ids e nomes
            for(int i = 0; i < usuarios.size(); i++) {
                tabela.adicionarRegistro(converterVoParaString(usuarios.get(i)));
            }

            return tabela;
        }
        
        return null;
    }
    
    /**
     * Transforma os campos de um VO em uma lista de Strings
     * 
     * @return lista de strings com os valores em ordem
     */
    public List<String> converterVoParaString(UsuarioVO usuario) {
        List<String> valores = new ArrayList<String>();
        
        valores.add(usuario.getIdUsuario().toString());
        valores.add(usuario.getNoUsuario());
        valores.add(usuario.getDsSenha());
        
        return valores;
    }
}
